home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / U-Z / VideoToolBox Folder / Demos / FlickeringGrating.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-04  |  5.5 KB  |  185 lines  |  [TEXT/KAHL]

  1. /*
  2. FlickeringGrating.c
  3. This demo displays a research-grade visual stimulus. If you just want to know
  4. how to load the clut and display a pattern, then you should start by reading
  5. Grating.c, which is much shorter and simpler.
  6. Copyright (c) 1989-1993 Denis G. Pelli
  7. HISTORY:
  8. 11/89     Lan & Denis wrote it.
  9. 23.1.90    dgp        Use second screen only if available.
  10. 4/9/90    dgp        Changed WindowPtr to CWindowPtr. Made big arrays static. Reduced
  11.                 default memory allocation to 1 megabyte. Use any 8-bit screen,
  12.                 preferably not the main screen.
  13. 4/23/90    dgp        Added optional timing. Centered the image. Left clut entries 0 and 
  14.                 colors-1 alone, so background doesn't flash. Asked if ISR Video 
  15.                 Attenuator is present.
  16. 10/11/90 dgp    Added fpu test.
  17. 10/29/90 dgp    Added CenterRectInRect().
  18. 10/30/90 dgp    Changed call to SetLuminances() to SetLuminancesAndRange() so that
  19.                 the range is now kept fixed throughout all the frames, to avoid
  20.                 flashes.
  21. 8/24/91    dgp        Made compatible with THINK C 5.0.
  22.                 If possible, use ReadLuminanceRecord().
  23. 3/10/92    dgp        include mc68881.h
  24. 4/26/92    dgp        RestoreCluts().
  25. 8/27/92    dgp        replace SysEnvirons() by Gestalt()
  26. 12/30/92 dgp    made more like Filter, using a small console so that, if necessary,
  27.                 both the console and the grating will fit on the main monitor.
  28. 2/7/93    dgp        replaced SetOnePixel by SetPixelsQuickly
  29. */
  30. #include "VideoToolbox.h"
  31. #include "Luminance.h"
  32. #include <math.h>
  33. #if THINK_C
  34.     #include <console.h>
  35.     #include <profile.h>
  36. #endif
  37.  
  38. #define SIZE         300            /* size of grating, in pixels */ 
  39. #define TMAX        3*67            /* duration, in frames, typically at 67 Hz */
  40. #define REPETITIONS    10            /* Number of times to repeat the animation */
  41. #define PROFILE        0            // optionally, report timing
  42.  
  43. void main(void);
  44. void FlickeringGrating(void);
  45. typedef struct{
  46.     ColorSpec table[256];
  47. }ColorSpecTable;
  48.  
  49. void main(void)
  50. {
  51.     Require(gestalt8BitQD);
  52.     FlickeringGrating();
  53. }
  54.     
  55. void FlickeringGrating(void)
  56. {
  57.     register int i;
  58.     int j,tmax,pixelSize,colors;
  59.     static double fX[SIZE],fY[SIZE];
  60.     double LMid,LMin,LMax,dL,a,contrast;
  61.     WindowPtr window=NULL, oldWindow=NULL;
  62.     GDHandle device=NULL;
  63.     static luminanceRecord LR;
  64.     static ColorSpecTable *tables[TMAX];    // an array of pointers to ColorSpec tables
  65.     static char string[100];
  66.     Rect r;
  67.     
  68.     #if PROFILE
  69.         InitProfile(200,3);    /* only needed if you want timing info */
  70.         _profile=0;
  71.     #endif
  72.     /* INITIALIZE QuickDraw */
  73.     #if THINK_C
  74.         console_options.top = 20;
  75.         console_options.nrows = 6;
  76.         printf("\n");
  77.     #else
  78.         InitGraf((Ptr) &thePort);
  79.         InitFonts();
  80.         InitWindows();
  81.         InitCursor();
  82.     #endif
  83.     printf("Welcome to FlickeringGrating.\n");
  84.     GetPort(&oldWindow);
  85.     for(i=8;i>=0;i--){
  86.         // look for a screen with 8-bit pixels.
  87.         device=GetScreenDevice(i);
  88.         if(device == NULL)continue;
  89.         pixelSize=(*(*device)->gdPMap)->pixelSize;
  90.         if(pixelSize==8)break;
  91.     }
  92.     if(pixelSize!=8 && NewPaletteManager())for(i=8;i>=0;i--){
  93.         // try to force a screen to 8-bit pixels.
  94.         device=GetScreenDevice(i);
  95.         if(device == NULL)continue;
  96.         SetDepth(device,8,1L<<gdDevType,1);
  97.         pixelSize=(*(*device)->gdPMap)->pixelSize;
  98.         if(pixelSize==8)break;
  99.     }
  100.     if(device==NULL || pixelSize != 8) PrintfExit("Sorry, I require 8 bits/pixel.\n");
  101.     window = GDOpenWindow1(device);
  102.     sprintf(string,"LuminanceRecord%d.h",i);
  103.     i=ReadLuminanceRecord(string,&LR,0);    /* try to read correct file */
  104.     if(i<=0){
  105.         #include "LuminanceRecord1.h"
  106.     }
  107.     printf("Using luminance calibration for screen %d calibrated %s by %s.\n"
  108.         ,LR.screen,LR.date,LR.notes);
  109.     printf("Have you installed an ISR Video Attenuator?(No):");
  110.     gets(string);
  111.     i=toupper(string[0]);
  112.     if(i!='Y'){
  113.         printf("No\n");
  114.         LR.r=0.0;
  115.         LR.g=1.0;
  116.         LR.b=0.0;
  117.     }
  118.     else printf("Yes\n");
  119.     #if PROFILE
  120.         _profile=1;
  121.     #endif
  122.  
  123.     /* load clut with linear gray scale */
  124.     // We'll leave clut entries 0 (white) and colors-1 (black) alone,
  125.     // since they are used heavily by Apple's stuff. Window frames
  126.     // will mostly look normal if we leave those two entries alone.
  127.     colors=(**(**(**device).gdPMap).pmTable).ctSize+1;
  128.     SetLuminances(device,&LR,1,colors-2,LR.LMin,LR.LMax);
  129.         
  130.     /* Display a sinusoid with a gaussian envelope */
  131.     // Compute the image.
  132.     SetPort(window);
  133.     PmBackColor(1+(long)(0.5+(colors-3)*0.5));
  134.     EraseRect(&window->portRect);
  135.     SetRect(&r,0,0,SIZE,SIZE);
  136.     CenterRectInRect(&r,&window->portRect);
  137.     for(i=0;i<SIZE;i++){
  138.         a=(i-SIZE/2)/(SIZE/6.);
  139.         fY[i]=exp(-a*a);
  140.         fX[i]=fY[i]*sin((i-SIZE/2)*(2.0*PI/80.0));
  141.     }
  142.     for(j=0;j<SIZE;j++){
  143.         unsigned long row[SIZE];
  144.         for(i=0;i<SIZE;i++) row[i]=1+(long)(0.5+(colors-3)*0.5*(1.0+fY[j]*fX[i]));
  145.         SetPixelsQuickly(r.left,j+r.top,row,SIZE);
  146.     }
  147.     // Allocate ColorSpec tables, one for each frame
  148.     for(i=0;i<TMAX;i++){
  149.         tables[i]= (ColorSpecTable *)NewPtr(sizeof(ColorSpecTable));
  150.         if(tables[i]==NULL){
  151.             printf("Only room for %d lookup tables (one per frame) ... continuing.\n",i);
  152.             break;
  153.         }
  154.     }
  155.     tmax=i;
  156.     // Compute lookup tables.
  157.     LMid=(LR.LMax+LR.LMin)/2.0;
  158.     contrast=(LR.LMax-LR.LMin)/(LR.LMax+LR.LMin);
  159.     LMax=LMid*(1.0+contrast);
  160.     LMin=LMid*(1.0-contrast);
  161.     for(i=0;i<tmax;i++){
  162.         a=6.0*(i-tmax/2)/tmax;
  163.         dL=LMid*contrast*exp(-a*a)*sin((i-tmax/2)*(2.0*PI*3.0*0.015));
  164.         SetLuminancesAndRange(NULL,&LR,1,colors-2,LMid-dL,LMid+dL,LMin,LMax);
  165.         *tables[i]= *(ColorSpecTable *)LR.table;
  166.     }
  167.     printf("Now displaying the animation ...\n");
  168.     for(j=0;j<REPETITIONS;j++){
  169.         for(i=0;i<tmax;i++){
  170.             // This is a thinly disguished call to GDSetEntries.
  171.             LoadLuminances(device,(luminanceRecord *) tables[i],1,colors-2);
  172.         }
  173.     }
  174.     #if PROFILE
  175.         _profile=0;
  176.     #endif
  177.     for(i=0;i<tmax;i++)DisposPtr((Ptr)tables[i]);
  178.     SetPort(oldWindow);
  179.     GDDisposeWindow1(window);
  180.     RestoreCluts();
  181.     #if !PROFILE
  182.         abort();
  183.     #endif
  184. }
  185.